﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UIObjects.TreeViewInterfaces;
#if SILVERLIGHT
using AbstraX.ClientInterfaces;
#else
using AbstraX.ServerInterfaces;
#endif
using System.Collections.ObjectModel;
using AbstraX.Contracts;
using MvvmTreeView;
using System.Windows.Controls;
using System.Windows;
using System.Diagnostics;
using SL4PopupMenu;

namespace AbstraX.ViewModels.ModelTree
{
    public class ModelTreeNodeRoot : ModelTreeNodeBase
    {
        private IRoot root;

        public ModelTreeNodeRoot(IProviderClientService providerService, ITreeView treeView, IRoot root) : base(providerService, treeView)
        {
            this.root = root;
            this.Tag = root;
            
#if HACK
            abstraXExtension = root.LoadExtension(root, this);
#endif
        }

        public override ContextMenu ContextMenu
        {
            get
            {
                ContextMenu contextMenu = null;
                ContextMenuItem buildMenuItem;
                
                RoutedEventHandler clickHandler = (sender, r) =>
                {
                    var menuItem = (PopupMenuItem)sender;
                    var invokeOperation = providerService.Build((string) menuItem.Tag);

                    invokeOperation.OnBuildCompleted += (sender2, e) =>
                    {
                        if (invokeOperation.HasException)
                        {
                            Debugger.Break();
                        }
                    };
                };

                buildMenuItem = new ContextMenuItem(null, "Build Middle Layer...", root.ID, ContextMenuItemType.View, clickHandler);

                if (abstraXExtension != null)
                {
                    contextMenu = abstraXExtension.ContextMenu;
                }

                if (contextMenu == null)
                {
                    contextMenu = new ContextMenu
                    {
                        Items = new List<IContextMenuItem>()
                        {
                            buildMenuItem
                        }
                    };
                }
                else
                {
                    contextMenu.Items.Add(buildMenuItem);
                }

                return contextMenu;
            }
            set
            {
                throw new NotImplementedException();
            }
        }

        public override void LoadChildren()
        {
            var root = (IRoot)this.Tag;

#if SILVERLIGHT
            root.ChildrenLoaded += new ChildrenLoadedHandler(ChildrenLoaded);
            root.LoadChildren();
#endif
            treeView.SetBusy(this, true);
        }


        public override IBase BaseObject
        {
            get
            {
                return root;
            }
        }

        public override void OnSelect()
        {
        }

        protected override void ChildrenLoaded(IBase parent)
        {
            isChildrenLoaded = true;

            this.RemoveSpinster();

            var elements = root.RootElements.AsQueryable().Cast<IElement>();
            var nodeIds = this.Nodes.Where(n => !(n.Tag is ModelTreeNodeFolder)).Select(n => (IBase)n.Tag).Select(b => b.ID);
            var folderElements = elements.Where(e => e.FolderKeyPair != null && e.FolderKeyPair.Length > 0).Cast<IBase>();
            var nonFolderElements = elements.Where(e => e.FolderKeyPair == null || e.FolderKeyPair.Length == 0);

            if (folderElements.Count() > 0)
            {
                var folderKeyPairs = folderElements.Select(e => e.FolderKeyPair).Distinct();

                folderKeyPairs
                .Select(fkp => new ModelTreeNodeFolder(providerService, treeView, fkp, folderElements.Where(f => f.FolderKeyPair == fkp)))
                .ToList()
                .ForEach(f => this.Nodes.Add(f));
            }

            nonFolderElements.AsQueryable()
            .Where(e => e.FolderKeyPair == null)
            .Select(r => new ModelTreeNodeElement(providerService, treeView, r)).Where(d => !nodeIds.Any(id => id == ((IBase)(d.Tag)).ID))
            .OrderBy(e => e.ChildOrdinal)
            .ThenBy(e => e.Text)
            .ToList()
            .ForEach(d => this.Nodes.Add(d));

            treeView.SetBusy(this, false);
        }

        public override string Text
        {
            get
            {
                return root.Name;
            }

            set
            {
                throw new NotImplementedException();
            }
        }

        public override List<string> AddNewShortCuts
        {
            get { throw new NotImplementedException(); }
        }

        public override void AddNew(string shortCut)
        {
            throw new NotImplementedException();
        }

        public override void DragStarting(object sender, UIObjects.DragDropInterfaces.ItemDragEventArgs e)
        {
        }

        public override void DragCompleted(object sender, UIObjects.DragDropInterfaces.ItemDragEventArgs e)
        {
        }

        public override void ItemDropped(object sender, UIObjects.DragDropInterfaces.ItemDragEventArgs e, int insertionIndex)
        {
        }

        public override void GiveFeedback(object sender, UIObjects.DragDropInterfaces.GiveFeedbackEventArgs e)
        {
        }

        public override void DragEnter(object sender, UIObjects.DragDropInterfaces.DragEventArgs e)
        {
        }

        public override void DragLeave(object sender, UIObjects.DragDropInterfaces.DragEventArgs e)
        {
        }

        public override void DragOver(object sender, UIObjects.DragDropInterfaces.DragEventArgs e)
        {
        }

        public override float ChildOrdinal
        {
            get
            {
                return root.ChildOrdinal;
            }
            set
            {
                throw new NotImplementedException();
            }
        }

        public override bool? HasChildren
        {
            get
            {
                return root.HasChildren;
            }
        }
    }
}
